#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : Tool.py
# @Author: Xuhao
# @Date  : 2018/1/24
# @Desc  :

import json
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import DeclarativeMeta

class Tool(object):

    @classmethod
    def decodeStr(cls, textStr):
        from binascii import b2a_hex, a2b_hex
        from Crypto.Cipher import DES

        key = '20141006'  # 长度必须是8位的
        text = b'xuhaowangyanxuyh'  # 长度必须是8的倍数,我用空格补的

        # 实例化
        obj = DES.new(key, )
        # # 加密
        # cryp = obj.encrypt(text)
        # pass_hex = b2a_hex(cryp)
        # print(pass_hex)


        # 解密
        get_cryp = a2b_hex(textStr)
        after_text = obj.decrypt(get_cryp)

        if after_text == text:
            return True
        return False

    @classmethod
    def new_alchemy_encoder(revisit_self=False, fields_to_expand=[]):
        _visited_objs = []

        class AlchemyEncoder(json.JSONEncoder):
            def default(self, obj):
                if isinstance(obj.__class__, DeclarativeMeta):
                    # don't re-visit self
                    if revisit_self:
                        if obj in _visited_objs:
                            return None
                        _visited_objs.append(obj)

                    # go through each field in this SQLalchemy class
                    fields = {}
                    for field in [x for x in dir(obj) if
                                  not x.startswith('_') and x != 'metadata' and hasattr(obj.__getattribute__(x),
                                                                                        '__call__') == False]:
                        val = obj.__getattribute__(field)

                        # is this field another SQLalchemy object, or a list of SQLalchemy objects?
                        if isinstance(val.__class__, DeclarativeMeta) or (
                                        isinstance(val, list) and len(val) > 0 and isinstance(val[0].__class__,
                                                                                              DeclarativeMeta)):
                            # unless we're expanding this field, stop here
                            if field not in fields_to_expand:
                                # not expanding this field: set it to None and continue
                                fields[field] = None
                                continue

                        fields[field] = val
                    # a json-encodable dict
                    return fields

                return json.JSONEncoder.default(self, obj)

        return AlchemyEncoder